import type { CSSProperties, FC } from 'react'
import React, { memo } from 'react'
import { useDrag, useDrop } from 'react-dnd'

import { ItemTypes } from './ItemTypes'

const style: CSSProperties = {
    border: '1px dashed gray',
    padding: '0.5rem 1rem',
    marginBottom: '.5rem',
    backgroundColor: 'white',
    cursor: 'move',
}

export interface CardProps {
    text: string
    moveCard: (id: number, to: number) => void
    index: number
}

interface Item {
    originalIndex: number
}

export const Card: FC<CardProps> = memo(function Card({
    text,
    moveCard,
    index
}) {
    const [{ isDragging }, drag] = useDrag(
        () => ({
            type: ItemTypes.CARD,
            item: { originalIndex: index },
            collect: (monitor) => ({
                isDragging: monitor.isDragging(),
            }),
            end: (item, monitor) => {
                const { originalIndex } = item
                const didDrop = monitor.didDrop()
                if (!didDrop) {
                    moveCard(index, originalIndex)
                }
            },
        }),
        [index, moveCard],
    )

    const [, drop] = useDrop(
        () => ({
            accept: ItemTypes.CARD,
            hover(item: Item) {
                const { originalIndex } = item
                if (originalIndex !== index) {
                    moveCard(originalIndex, index)
                    item.originalIndex = index
                }
            },
        }),
        [index, moveCard],
    )

    const opacity = isDragging ? 0 : 1
    return (
        <div ref={(node) => drag(drop(node))} style={{ ...style, opacity }}>
            {text}
        </div>
    )
})
